home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
music4c.sit
/
Music4C Folder
/
SFInfo folder
/
SFInfoMain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-11
|
33KB
|
1,442 lines
/*
* Tells about SoundFiles
*/
#include "SFInfo.h"
#include "AIFFType.h"
#include <stdio.h>
#include <unix.h>
#include <string.h>
#include <math.h>
#include <SANE.h>
#include "SFInfoProtos.h"
int FileOpen;
long TotalSamps;
CursHandle watchCurs;
int SoundFileType;
long SampleRate;
long NumChannels;
double MaxSample;
double MinSample;
long SoundFileDirID;
long StartUpDirID;
long fileSize;
Str255 SoundFileName;
Str255 myStr;
ioParam myIOParmBlk;
Boolean SDnoResource;
SFReply SoundFileReply;
WDPBRec myWDParamBlk;
Point where;
FileParam fPB;
Str255 SFDirectoryName;
int SFSaveVRef;
OSErr theErr;
Str255 theMess1;
Str255 theMess2;
SysEnvRec SysEnvData;
int nrec;
/*
* Types used for Sound Designer File format specification
*
*
* this format seems ok, gg. 8 Nov 88
*
*/
/*
typedef enum { leftSide, rightSide
} SideType;
typedef enum {
tTime,SampleNumber,HexSampNum,Volts,Percent,dbm,User
} ScaleNames;
*/
typedef enum {
Select,Draw,ZoomSelect
} ModeType;
typedef struct MarkerType {
Boolean Free; /* Boolean */
long Position;
char Name[34];
} MarkerType;
typedef struct EditRecord {
long HiAddr;
long LoAddr;
Boolean ExtendSide; /* SideType */
} EditRecord;
typedef struct ZoomType {
int v;
long h;
} ZoomType;
typedef struct ScaleType {
long VFactor;
int VType; /* ScaleNames */
char VString[34];
long HFactor;
int HType; /* ScaleNames */
char HString[34];
} ScaleType;
typedef struct WaveRec {
int HeaderSize;
int Version;
int Preview; /* Boolean */
WindowPtr WPtr;
WindowPeek WPeek;
long HInxPage,HInxLine;
long VInxPage,VInxLine;
long HCtlPage,HCtlLine;
long VCtlPage,VCtlLine;
long VOffset,HOffset;
int VOffConst;
ZoomType ZF;
ScaleType SF;
int VScrUpdate;
Ptr BufPtr;
Size BufBytes;
long BufOffset;
RgnHandle WaveRgn,ClipArea,ScaleArea;
Rect CtlWidth;
ControlHandle VScroll,HScroll;
Size FileSize;
char BUName[66];
char FileName[66];
int BURefNum;
int refNum;
int vRefNum;
Boolean BufChanged; /* Boolean */
Boolean FileChanged; /* Boolean */
Boolean NoBackup; /* Boolean */
ModeType Mode; /* ModeType */
EditRecord Edit;
long CursorPos;
RgnHandle CursorRgn;
MarkerType MarkerData[10]; /* 10 */
long MarkerOffset;
long LoopStart;
long LoopEnd;
Boolean ZeroLineOn; /* Boolean */
Boolean CursorOn; /* Boolean */
int ScalesOn; /* Boolean */
Str255 Comment;
long SampRate;
long SampPeriod;
int SampSize;
char CodeType[34];
Str255 UserStr1;
Size BufSize;
long Loop2Start;
long Loop2End;
SignedByte Loop1Type;
SignedByte Loop2Type;
int User4;
} WaveRec, *WavPtr;
main()
{
SetApplLimit(GetApplLimit());
MaxApplZone();
MoreMasters();
init_process();
CheckSystem();
if ( OpenSFRread() ) {
ShowInfo();
}
CloseSF();
event_loop();
ExitToShell();
} /* main */
ProcPtr restartProc()
{
ExitToShell();
}
void init_process()
{
init_mgrs();
init();
fill_menus();
}
void init_mgrs()
{
InitGraf(&thePort);
InitFonts();
FlushEvents(everyEvent, 0 );
InitWindows();
InitCursor();
InitMenus();
TEInit();
InitDialogs(restartProc);
}
void init()
{
SFDirectoryName[0] = 0;
GetMusic4C_Prefs();
FileOpen = 0;
watchCurs = GetCursor(watchCursor);
}
void identify()
{
DialogPtr aboutBox;
EventRecord event;
PicHandle thePic;
Rect myRect, tempRect;
aboutBox = GetNewDialog(ABOUT_DIALOG, NIL, -1L);
tempRect.top = aboutBox->portRect.top;
tempRect.left = aboutBox->portRect.left;
tempRect.bottom = aboutBox->portRect.bottom;
tempRect.right = aboutBox->portRect.right;
tempRect.top = ((screenBits.bounds.bottom - screenBits.bounds.top) - (tempRect.bottom - tempRect.top)) / 2;
tempRect.left = ((screenBits.bounds.right - screenBits.bounds.left) - (tempRect.right - tempRect.left)) / 2;
MoveWindow(aboutBox, tempRect.left, tempRect.top, TRUE);
ParamText("\p", NIL, NIL, NIL);
ShowWindow(aboutBox);
SelectWindow(aboutBox);
DrawDialog(aboutBox);
SetPort(aboutBox);
while( !EventAvail(keyDownMask|autoKeyMask|mDownMask, &event))
SystemTask();
if ( event.what == mouseDown ) {
GlobalToLocal(&event.where);
if ( PtInRect(event.where, &aboutBox->portRect))
GetNextEvent(mDownMask, &event);
}
DisposDialog(aboutBox);
}
void fill_menus()
{
if (GetResource('MENU', APPLE_MENU)==0) {
SysBeep(20);
PstringCopy((char *)theMess1,"\pCan't open resource file");
errorAlert(theMess1, NIL);
return;
}
AppendMenu(GetMenu(APPLE_MENU), CtoPstr("About SFInfo..."));
AppendMenu(GetMenu(APPLE_MENU), CtoPstr("(-"));
AddResMenu(GetMenu(APPLE_MENU), 'DRVR');
InsertMenu(GetMenu(APPLE_MENU), 0);
InsertMenu(GetMenu(FILE_MENU), 0);
DisableItem(GetMHandle(FILE_MENU), 2);
DrawMenuBar();
}
void event_loop()
{
EventRecord event;
char c;
FlushEvents(everyEvent, 0 );
while (TRUE) {
while(GetNextEvent(everyEvent, &event)) {
SystemTask(); /* do DA's */
switch(event.what) {
case mouseDown:
do_mouse_down(&event);
break;
case mouseUp:
break;
case keyDown:
c = event.message & charCodeMask;
if(event.modifiers & cmdKey)
do_menu(MenuKey(c));
break;
case keyUp:
break;
case autoKey:
break;
case updateEvt:
case diskEvt:
break;
case activateEvt:
break;
case networkEvt:
case driverEvt:
case app1Evt:
case app2Evt:
case app3Evt:
case app4Evt:
default:
break;
}
}
}
}
void do_mouse_down(event)
EventRecord *event;
{
WindowPtr windowp;
int windowCode = FindWindow(MK_LONG(event->where), &windowp);
switch(windowCode) {
case inDesk:
break;
case inMenuBar:
do_menu(MenuSelect(MK_LONG(event->where)));
break;
case inSysWindow:
SystemClick(event, windowp);
break;
case inContent:
break;
case inDrag:
break;
case inGrow:
break;
case inGoAway:
break;
default:
break;
}
}
void do_menu(command)
long command;
{
int menu_id = HiWord(command);
int item = LoWord(command);
char item_name[32];
switch(menu_id) {
case APPLE_MENU:
if ( item == AboutItem)
identify();
else {
GetItem(GetMHandle(menu_id), item, item_name);
OpenDeskAcc(item_name);
}
break;
case FILE_MENU:
switch(item) {
case OPEN:
if ( OpenSFRread() ) {
ShowInfo();
}
CloseSF();
break;
case QUIT:
Finish();
break;
}
break;
}
HiliteMenu(0);
}
void Finish()
{
ExitToShell();
}
Boolean OpenSFRread()
{
SFTypeList types;
extern ioParam myIOParmBlk;
extern Str255 SoundFileName;
extern long StartUpDirID;
extern long SoundFileDirID;
extern int SFSaveVRef;
extern long fileSize;
extern int SoundFileType;
extern long NumChannels;
extern double MaxSample;
extern double MinSample;
extern Boolean SDnoResource;
extern Str255 SFDirectoryName;
long sfResFileRefNum;
Str255 resString;
Str255 myString;
Handle myHndl;
StringHandle aString;
int wdRefNum;
int i;
char c0, c1, c2, c3;
if ( SFDirectoryName[0] != NIL ) {
if ( !SetSFDir(SFDirectoryName, &SoundFileDirID) ) {
CurDirStore = StartUpDirID;
return(FALSE);
}
}
SetPt(&where, 100, 100);
SFGetFile(where, NIL, NIL, -1, NIL, NIL, &SoundFileReply);
if(!SoundFileReply.good) {
CurDirStore = StartUpDirID;
return(FALSE);
}
GetSFDir(&SFDirectoryName);
/* we now have the directory where the sound file is to be created */
SetSFDir(SFDirectoryName, &SoundFileDirID);
SFSaveVRef = SoundFileReply.vRefNum;
PstringCopy((char *)SoundFileName, (char *)SoundFileReply.fName);
myIOParmBlk.ioNamePtr = (StringPtr)SoundFileName;
myIOParmBlk.ioVRefNum = SoundFileReply.vRefNum;
myIOParmBlk.ioVersNum = SoundFileReply.version;
myIOParmBlk.ioPermssn = fsRdWrPerm;
if ( (theErr = PBOpen(&myIOParmBlk, FALSE) )!= noErr) {
PstringCopy((char *)theMess1,"\pError opening file");
errorAlert(theMess1, NIL);
}
myIOParmBlk.ioCompletion = NIL;
PBGetEOF(&myIOParmBlk, FALSE);
if ( (fileSize = (long)myIOParmBlk.ioMisc) <= 0 ) {
PstringCopy((char *)theMess1,"\pFile is empty!");
errorAlert(theMess1, NIL);
return(FALSE);
}
/* now read the resource part */
/* first check if it is a Sound Designer file */
fPB.ioCompletion = (ProcPtr)NIL;
fPB.ioNamePtr = myIOParmBlk.ioNamePtr;
fPB.ioVRefNum = myIOParmBlk.ioVRefNum;
fPB.ioFVersNum = myIOParmBlk.ioVersNum;
fPB.ioFDirIndex = NIL;
theErr = PBGetFInfo(&fPB, FALSE);
if ( (fPB.ioFlFndrInfo.fdType == 'TEXT') && (fPB.ioFlFndrInfo.fdCreator = 'MU4C' ) )
SoundFileType = FLOAT;
else if ( fPB.ioFlFndrInfo.fdType == 'SFIL' )
SoundFileType = SD1;
else if ( fPB.ioFlFndrInfo.fdType == 'Sd2f' )
SoundFileType = SD2;
else if ( fPB.ioFlFndrInfo.fdType == 'AIFF' )
SoundFileType = AIFF;
else {
PstringCopy((char *)theMess1, "\pUnknown sound file type");
sprintf((char *)theMess2, "%c%c%c%c",
(char)((fPB.ioFlFndrInfo.fdType & 0xFF000000) >> 24),
(char)((fPB.ioFlFndrInfo.fdType & 0x00FF0000) >> 16),
(char)((fPB.ioFlFndrInfo.fdType & 0x0000FF00) >> 8),
(char)(fPB.ioFlFndrInfo.fdType & 0x000000FF));
CtoPstr((char *)theMess2);
errorAlert(theMess1, theMess2);
return(FALSE);
}
sfResFileRefNum = OpenResFile(SoundFileName);
SDnoResource = FALSE;
if ((theErr = ResError()) != noErr) {
if ( SoundFileType != SD1 && SoundFileType != SD1 && SoundFileType != AIFF) {
PstringCopy((char *)theMess1, "\pError opening resource file: ");
OSError2(theMess1, SoundFileName, theErr);
return(FALSE);
}
else {
SDnoResource = TRUE;
}
return(TRUE);
}
else {
GetIndString(&resString, SFRESOURCENUM, 1);
PtoCstr((char *)resString);
if ( strcmp("FLOAT", (char *)resString) == 0 ) {
SoundFileType = FLOAT;
}
else if ( strcmp("INT16", (char *)resString) == 0 ) {
SoundFileType = INT16;
}
else if ( strcmp("SD", (char *)resString) == 0 )
SoundFileType = SD1;
else if ( strcmp("SD1", (char *)resString) == 0 )
SoundFileType = SD1;
else if ( strcmp("SD2", (char *)resString) == 0 ) {
SoundFileType = SD2;
myHndl = GetResource('STR ', SAMPLE_RATE_RES );
if ( myHndl && (theErr = ResError()) == noErr) {
aString = (StringHandle)GetString(SAMPLE_RATE_RES);
HLock(aString);
PstringCopy((char *)myString, (char *)*aString);
PtoCstr((char *)myString);
/* "cast" to integer value */
i = strcspn((char *)myString, ".");
if ( i > 0 )
myString[i] = '\0';
CtoPstr((char *)myString);
StringToNum(myString, &SampleRate);
HUnlock(aString);
DisposHandle(aString);
SoundFileType = SD2;
myHndl = GetResource('STR ', SAMPLE_CHANNELS_RES );
if ((theErr = ResError()) == noErr) {
aString = (StringHandle)GetString(SAMPLE_CHANNELS_RES);
HLock(aString);
StringToNum(*aString, &NumChannels);
HUnlock(aString);
}
DisposHandle(aString);
DisposHandle(myHndl);
}
else
SDnoResource = TRUE;
}
else if ( strcmp("AIFF", (char *)resString) == 0 ) {
SoundFileType = AIFF;
}
else if ( strcmp("", (char *)resString) == 0 ) {
myHndl = GetResource('STR ', SAMPLE_RATE_RES );
if ( myHndl && (theErr = ResError()) == noErr) {
aString = (StringHandle)GetString(SAMPLE_RATE_RES);
HLock(aString);
PstringCopy((char *)myString, (char *)*aString);
PtoCstr((char *)myString);
/* "cast" to integer value */
i = strcspn((char *)myString, ".");
if ( i > 0 )
myString[i] = '\0';
CtoPstr((char *)myString);
StringToNum(myString, &SampleRate);
HUnlock(aString);
DisposHandle(aString);
SoundFileType = SD2;
myHndl = GetResource('STR ', SAMPLE_CHANNELS_RES );
if ((theErr = ResError()) == noErr) {
aString = (StringHandle)GetString(SAMPLE_CHANNELS_RES);
HLock(aString);
StringToNum(*aString, &NumChannels);
HUnlock(aString);
}
DisposHandle(aString);
DisposHandle(myHndl);
}
else if (SoundFileType != AIFF)
SoundFileType = SD1;
SDnoResource = TRUE;
CloseResFile(sfResFileRefNum);
return(TRUE);
}
else {
CtoPstr((char *)resString);
PstringCopy((char *)theMess1,"\pUnknown Sound file type");
errorAlert(theMess1, resString);
return(FALSE);
}
GetIndString(&resString, SFRESOURCENUM, 2);
StringToNum(resString, &NumChannels);
if ( NumChannels > 4L ) {
PstringCopy((char *)theMess1,"\pmono, stereo or quad soundfiles");
errorAlert(theMess1, NIL);
CloseResFile(sfResFileRefNum);
return(FALSE);
}
GetIndString(&resString, SFRESOURCENUM, 3);
StringToNum(resString, &SampleRate);
GetIndString(&resString, SFRESOURCENUM, 4);
PtoCstr((char *)resString);
sscanf((char *)resString, "%lf", &MaxSample);
GetIndString(&resString, SFRESOURCENUM, 5);
PtoCstr((char *)resString);
sscanf((char *)resString, "%lf", &MinSample);
CloseResFile(sfResFileRefNum);
}
CloseResFile(sfResFileRefNum);
return(TRUE);
}
void ShowInfo()
{
DialogPtr myDialog;
int itemHit;
Str255 theString;
int itype;
Handle hndl;
Rect box;
long nSamps;
double theTime;
extern CursHandle watchCurs;
int i;
Rect tempRect;
SetCursor(*watchCurs);
/* put up the dialog box with the info */
myDialog = GetNewDialog(InfoDialog, NIL, (WindowPtr) -1);
tempRect.top = myDialog->portRect.top;
tempRect.left = myDialog->portRect.left;
tempRect.bottom = myDialog->portRect.bottom;
tempRect.right = myDialog->portRect.right;
tempRect.top = ((screenBits.bounds.bottom - screenBits.bounds.top) - (tempRect.bottom - tempRect.top)) / 2;
tempRect.left = ((screenBits.bounds.right - screenBits.bounds.left) - (tempRect.right - tempRect.left)) / 2;
MoveWindow(myDialog, tempRect.left, tempRect.top, TRUE);
ParamText("\p", NIL, NIL, NIL);
ShowWindow(myDialog);
SelectWindow(myDialog);
DrawDialog(myDialog);
SetPort(myDialog);
/* figure it all out */
GetDItem(myDialog, TypeItem, &itype, &hndl, &box);
switch(SoundFileType) {
case FLOAT:
PstringCopy((char *)theString, "\pFLOAT");
break;
case INT16:
PstringCopy((char *)theString, "\pINT16");
break;
case SD1:
PstringCopy((char *)theString, "\pSound Designer");/* ????? */
break;
case SD2:
PstringCopy((char *)theString, "\pSound Designer II");
break;
case AIFF:
PstringCopy((char *)theString, "\pAIFF");
break;
default:
PstringCopy((char *)theString, "\p");
break;
}
SetIText(hndl, theString);
switch(SoundFileType) {
case FLOAT:
nSamps = fileSize / sizeof(float);
if ( NumChannels > 0 )
nSamps /= NumChannels;
else
NumChannels = 1L;
theTime = (double)nSamps / SampleRate;
break;
case INT16:
nSamps = fileSize / sizeof(int);
if ( NumChannels > 0 )
nSamps /= NumChannels;
else
NumChannels = 1L;
theTime = (double)nSamps / SampleRate;
break;
case SD2:
if ( !SD2Info() )
break;
nSamps = fileSize / sizeof(int);
theTime = (double)nSamps / SampleRate / NumChannels;
break;
case SD1:
if ( !SD1Info() )
break;
nSamps = fileSize / sizeof(int);
theTime = (double)nSamps / SampleRate;
NumChannels = 1L;
break;
case AIFF:
if (!AIFFInfo() )
break;
nSamps = fileSize / sizeof(int);
theTime = (double)nSamps / SampleRate;
break;
default:
nSamps = 0L;
theTime = 0.0;
break;
}
GetDItem(myDialog, ChanItem, &itype, &hndl, &box);
NumToString(NumChannels, &theString);
SetIText(hndl, theString);
GetDItem(myDialog, SrateItem, &itype, &hndl, &box);
NumToString(SampleRate, &theString);
SetIText(hndl, theString);
GetDItem(myDialog, MaxAmpItem, &itype, &hndl, &box);
sprintf((char *)theString, "%lf", MaxSample);
CtoPstr((char *)theString);
SetIText(hndl, theString);
GetDItem(myDialog, MinAmpItem, &itype, &hndl, &box);
sprintf((char *)theString, "%lf", MinSample);
CtoPstr((char *)theString);
SetIText(hndl, theString);
/* calculate file duration */
if ( fileSize == 0L ) {
GetDItem(myDialog, LengthTimeItem, &itype, &hndl, &box);
PstringCopy((char *)theString, "\p0");
SetIText(hndl, theString);
GetDItem(myDialog, LengthSampsItem, &itype, &hndl, &box);
PstringCopy((char *)theString, "\p0");
SetIText(hndl, theString);
}
else {
GetDItem(myDialog, LengthTimeItem, &itype, &hndl, &box);
i = sprintf((char *)theString, "%lf", theTime);
CtoPstr((char *)theString);
SetIText(hndl, theString);
GetDItem(myDialog, LengthSampsItem, &itype, &hndl, &box);
NumToString(nSamps, &theString);
SetIText(hndl, theString);
}
GetDItem(myDialog, TitleItem, &itype, &hndl, &box);
SetIText(hndl, SoundFileReply.fName);
InitCursor();
ShowWindow((WindowPtr)myDialog);
OutLineButton(myDialog, theUserItem);
itemHit = 0;
while ( itemHit != OKButton)
ModalDialog((ProcPtr)NIL, &itemHit);
DisposDialog(myDialog);
}
Boolean CloseSF()
{
extern ioParam myIOParmBlk;
extern ioParam NewParmBlk;
if ( (theErr = PBClose(&myIOParmBlk, FALSE)) != noErr ) {
/* PstringCopy((char *)theMess1,"\pError closing Sound File: ", SoundFileName, theErr);*/
return(FALSE);
}
fPB.ioCompletion = (ProcPtr)NIL;
fPB.ioNamePtr = myIOParmBlk.ioNamePtr;
fPB.ioVRefNum = myIOParmBlk.ioVRefNum;
fPB.ioFVersNum = myIOParmBlk.ioVersNum;
fPB.ioFDirIndex = NIL;
if ( (theErr = PBFlushVol(&fPB, FALSE)) != noErr ) {
PstringCopy((char *)theMess1,"\pError returned from PBFlushVol for sample file's volume:");
NumToString(theErr, &theMess2);
OSError(theMess1, theMess2);
return(FALSE);
}
return(TRUE);
}
Boolean SetSFDir(DirName, theDirID)
Str255 DirName;
long *theDirID;
{
extern int SFSaveVRef;
extern int ReportFileRefNum;
Str255 aString;
PstringCopy((char *)aString, (char *)DirName);
myWDParamBlk.ioNamePtr = (StringPtr)aString;
myWDParamBlk.ioCompletion = NIL;
myWDParamBlk.ioVRefNum = 0;
myWDParamBlk.ioWDDirID = NIL;
if ( (theErr = PBHSetVol(&myWDParamBlk, FALSE)) != noErr ) {
/* OSError2("\pSetSFDir error: PBHSetVol", myWDParamBlk.ioNamePtr, (long)theErr);
return(FALSE);
*/
}
PBHGetVol(&myWDParamBlk, FALSE);
*theDirID = myWDParamBlk.ioWDDirID;
CurDirStore = *theDirID;
SFSaveVRef = myWDParamBlk.ioVRefNum;
SFSaveDisk = -1 * SFSaveVRef;
return(TRUE);
}
void OutLineButton(theDialog, itemNo)
DialogPtr theDialog;
int itemNo;
{
int itype;
Rect buttonRect;
Handle aHandl;
GrafPtr tempPort;
GetPort(&tempPort);
SetPort(theDialog);
GetDItem(theDialog, itemNo, &itype, &aHandl, &buttonRect);
PenSize(3,3);
InsetRect(&buttonRect, -4, -4);
FrameRoundRect(&buttonRect, 16, 16);
PenSize(1,1);
SetPort(tempPort);
}
void OSError(msg1, msg2)
Str255 msg1, msg2;
{
short i;
if (msg2[0] != 0)
ParamText(msg1, msg2, "\p", "\p");
else
ParamText(msg1, "\p", "\p", "\p");
i = CautionAlert(401, NIL);
}
void OSError2(msg1, msg2, errNum)
Str255 msg1, msg2;
long errNum;
{
Str255 numMsg;
short i;
NumToString((long)errNum, &numMsg);
ParamText(msg1, msg2, numMsg, NIL);
i = CautionAlert(401, NIL);
}
void DoOSErrorAlert(mess1, mess2)
Str255 mess1, mess2;
{
ParamText(mess1, mess2, NIL, NIL);
CautionAlert(401, NIL);
}
void PstringCopy(to, from)
char *to, *from;
{
char *end = from + *from + 1;
for ( *to++ = *from++; from < end; )
*to++ = *from++;
}
void PstringCat(to, from)
char *to, *from;
{
register int i, length;
char *p;
length = *from;
p = to + *to + 1;
from++;
for ( i = 0; i < length; i++) *p++ = *from++;
*to += length;
}
/*-------------------------------------------------------------------------------*/
int stcisn(s, set)
register char *s;
char *set;
{
register char *t;
register int count = 0;
/* find position of set in s */
while (*s)
{
t = set;
while (*t && (*s != *t)) t++;
if (!*t)
{
s++;
count++;
}
else
break;
}
return (count);
}
void errorAlert(mess1, mess2)
Str255 mess1, mess2;
{
if ( mess2 )
ParamText(mess1, mess2, "\p", "\p");
else
ParamText(mess1, "\p", "\p", "\p");
CautionAlert(401, NIL);
}
Boolean AIFFInfo()
{
register long i;
register double scalefactor;
register double x;
double peak;
int *theIbuf, *Iptr;
float *sp, *SampBuf;
long nBytes;
long nSamps;
long bytesLeft;
long sampBufsz;
Chunk FormChunkHeader, *FormChunkHeaderPtr;
CommonChunk CommonHeader, *CommonHeaderPtr;
SoundDataChunk SoundDataHeader, *SoundDataHeaderPtr;
BasicChunk BaseChunk, *BaseChunkPtr;
long aLong, *aLongPtr;
Boolean found;
Fixed aFix;
decform mydecform;
Str255 myStr255;
long RecLength;
FormChunkHeaderPtr = &FormChunkHeader;
CommonHeaderPtr = &CommonHeader;
SoundDataHeaderPtr = &SoundDataHeader;
myIOParmBlk.ioCompletion = 0L;
myIOParmBlk.ioPosMode = fsFromStart;
myIOParmBlk.ioPosOffset = 0L;
theErr = PBSetFPos(&myIOParmBlk, FALSE);
myIOParmBlk.ioBuffer = (Ptr)FormChunkHeaderPtr;
myIOParmBlk.ioReqCount = sizeof(FormChunkHeader);
theErr = PBRead(&myIOParmBlk, FALSE);
if ( FormChunkHeader.ckID != 'FORM' ) {
PstringCopy((char *)theMess1, "\pError reading AIFF file, FORM header");
DoOSErrorAlert(theMess1, NIL);
return(FALSE);
}
BaseChunkPtr = &BaseChunk;
found = FALSE;
while ( !found ) {
myIOParmBlk.ioBuffer = (Ptr)BaseChunkPtr;
myIOParmBlk.ioReqCount = sizeof(BaseChunk);
theErr = PBRead(&myIOParmBlk, FALSE);
if ( theErr == eofErr ) {
DoOSErrorAlert("\pError: EOF reading reading AIFF file, no COMM header", NIL);
return(FALSE);
}
if ( BaseChunk.ckID == 'COMM' ) {
found = TRUE;
myIOParmBlk.ioPosMode = fsFromMark;
myIOParmBlk.ioPosOffset = -myIOParmBlk.ioActCount;
theErr = PBSetFPos(&myIOParmBlk, FALSE);
myIOParmBlk.ioPosMode = fsAtMark;
/* get the common chunk info */
myIOParmBlk.ioBuffer = (Ptr)CommonHeaderPtr;
myIOParmBlk.ioReqCount = sizeof(CommonHeader);
theErr = PBRead(&myIOParmBlk, FALSE);
aFix = X2Fix( &CommonHeader.sampleRate);
SampleRate = (long) aFix;
mydecform.style = 1;
mydecform.digits = -1;
num2str(&mydecform, CommonHeader.sampleRate, &myStr255);
StringToNum(myStr255, &SampleRate );
NumChannels = CommonHeader.numChannels;
}
else { /* skip this chunk */
myIOParmBlk.ioPosMode = fsFromMark;
myIOParmBlk.ioPosOffset = BaseChunk.ckSize;
theErr = PBSetFPos(&myIOParmBlk, FALSE);
if ( theErr == eofErr ) {
DoOSErrorAlert("\pError: EOF reading reading AIFF file, no COMM header", NIL);
return(FALSE);
}
myIOParmBlk.ioPosMode = fsAtMark;
}
}
/* rewind to start of FORM */
myIOParmBlk.ioPosMode = fsFromStart;
myIOParmBlk.ioPosOffset = sizeof(FormChunkHeader);
theErr = PBSetFPos(&myIOParmBlk, FALSE);
if ( theErr != noErr ) {
DoOSErrorAlert("\pError re-positioning file to start of FORM", NIL);
return(FALSE);
}
/* now look for SSND Chunk */
found = FALSE;
while ( !found ) {
myIOParmBlk.ioBuffer = (Ptr)BaseChunkPtr;
myIOParmBlk.ioReqCount = sizeof(BaseChunk);
theErr = PBRead(&myIOParmBlk, FALSE);
if ( theErr == eofErr ) {
DoOSErrorAlert("\pError: EOF reading reading AIFF file, no SSND header", NIL);
return(FALSE);
}
if ( BaseChunk.ckID == 'SSND' ) {
found = TRUE;
myIOParmBlk.ioPosMode = fsFromMark;
myIOParmBlk.ioPosOffset = -myIOParmBlk.ioActCount;
theErr = PBSetFPos(&myIOParmBlk, FALSE);
myIOParmBlk.ioPosMode = fsAtMark;
/* get the common chunk info */
myIOParmBlk.ioBuffer = (Ptr)SoundDataHeaderPtr;
myIOParmBlk.ioReqCount = sizeof(SoundDataHeader);
theErr = PBRead(&myIOParmBlk, FALSE);
}
else { /* skip this chunk */
myIOParmBlk.ioPosMode = fsFromMark;
myIOParmBlk.ioPosOffset = BaseChunk.ckSize;
theErr = PBSetFPos(&myIOParmBlk, FALSE);
if ( theErr == eofErr ) {
DoOSErrorAlert("\pError reading AIFF file, no SSND header", NIL);
return(FALSE);
}
myIOParmBlk.ioPosMode = fsAtMark;
}
};
/* we only get here if we have found FORM, COMM and SSND chunks */
RecLength = (long)16384;
nrec = 0;
scalefactor = 2.0/65535.0;
MinSample = 0.0;
MaxSample = 0.0;
sampBufsz = RecLength / sizeof(int);
theIbuf = (int *)NewPtr(sizeof(int) * sampBufsz);
if ( (theErr = MemError()) != noErr ) {
DoOSErrorAlert("\pcan't get enough memory for theIbuf", NIL);
return(FALSE);
}
SampBuf = (float *)NewPtr( sizeof(float) * sampBufsz);
if ( (theErr = MemError()) != noErr ) {
DoOSErrorAlert("\pcan't get enough memory for SampBuf", NIL);
return(FALSE);
}
bytesLeft = SoundDataHeader.ckSize - sizeof(SoundDataHeader.offset)
- sizeof(SoundDataHeader.blockSize);
fileSize = bytesLeft;
myIOParmBlk.ioPosMode = fsAtMark;
myIOParmBlk.ioPosOffset = NIL;
while ( bytesLeft > 0L ) {
if ( bytesLeft > RecLength )
nBytes = RecLength;
else
nBytes = bytesLeft;
myIOParmBlk.ioBuffer = (Ptr)theIbuf;
myIOParmBlk.ioReqCount = nBytes;
theErr = PBRead(&myIOParmBlk, FALSE);
if (theErr != noErr ) {
if ( theErr == eofErr )
DoOSErrorAlert("\pEnd of file reached", NIL);
}
nBytes = myIOParmBlk.ioActCount;
if ( nBytes != myIOParmBlk.ioReqCount ) {
if ( theErr != eofErr ) {
DoOSErrorAlert("\pRead less bytes than expected", NIL);
}
if ( nBytes == 0L ) {
DisposPtr((Ptr)SampBuf);
DisposPtr((Ptr)theIbuf);
return(FALSE);
}
}
nSamps = nBytes / sizeof(int);
for ( i = 0, Iptr = theIbuf, sp = SampBuf; i < nSamps; i++ ) {
*sp = (*Iptr++ * scalefactor);
if ( *sp < MinSample )
MinSample = *sp;
else if ( *sp > MaxSample )
MaxSample = *sp;
sp++;
}
nrec++;
bytesLeft -= nBytes;
}
DisposPtr((Ptr)SampBuf);
DisposPtr((Ptr)theIbuf);
InitCursor();
return(TRUE);
}
/*-------------------------------------------------------------------------------*/
Boolean GetSFDir(DirName)
Str255 *DirName;
{
Str255 myStr;
WDPBRec myWDParamBlk;
DirInfo myCatInfoBlk;
myCatInfoBlk.ioCompletion = NIL;
myCatInfoBlk.ioVRefNum = -SFSaveDisk;
myCatInfoBlk.ioDrDirID = CurDirStore;
myCatInfoBlk.ioFDirIndex = -1;
myCatInfoBlk.ioNamePtr = (StringPtr)myStr;
if ( (theErr = PBGetCatInfo(&myCatInfoBlk, FALSE)) != noErr ) {
PstringCopy((char *)theMess1, "\pError getting SoundFile Directory: PBGetCatInfo");
NumToString(theErr, &theMess2);
OSError(theMess1, theMess2);
return(FALSE);
}
PstringCopy((char *)DirName, (char *)myStr);
PstringCat((char *)DirName, "\p:");
while (myCatInfoBlk.ioDrDirID != 2 ) {
myCatInfoBlk.ioDrDirID = myCatInfoBlk.ioDrParID;
if ( (theErr = PBGetCatInfo(&myCatInfoBlk, FALSE)) != noErr ) {
PstringCopy((char *)theMess1, "\Error in GetSFDir: PBGetCatInfo");
NumToString(theErr, &theMess2);
OSError(theMess1, theMess2);
return(FALSE);
}
PstringCat((char *)myStr, "\p:");
PstringCat((char *)myStr, (char *)DirName);
PstringCopy((char *)DirName, (char *)myStr);
}
CurDirStore = myCatInfoBlk.ioDrDirID;
return(TRUE);
}
Boolean SD1Info()
{
register double x;
register int i;
WaveRec Header;
WavPtr HeaderPtr;
long nBytes;
OSErr theErr;
long sampBufsz;
long bytesLeft;
long RecLength = 2048L;
long nSamps;
Str255 aString;
int *theIbuf, *Iptr;
/* read the header */
HeaderPtr = &Header;
nBytes = sizeof(Header.HeaderSize);
myIOParmBlk.ioPosMode = fsFromStart;
myIOParmBlk.ioPosOffset = 0L;
myIOParmBlk.ioBuffer = (Ptr)HeaderPtr;
myIOParmBlk.ioReqCount = nBytes;
theErr = PBRead(&myIOParmBlk, FALSE);
if (theErr != noErr ) {
if ( theErr == eofErr ) {
PstringCopy((char *)theMess1, "\pEnd of file reached Header");
errorAlert(theMess1, NIL);
return(FALSE);
}
else {
NumToString(theErr, &aString);
PstringCopy((char *)theMess1, "\pError reading Header");
errorAlert(theMess1, aString);
return(FALSE);
}
}
if ( myIOParmBlk.ioActCount != nBytes ) {
PstringCopy((char *)theMess1, "\pError reading HeaderSize");
errorAlert(theMess1, NIL);
}
nBytes = Header.HeaderSize;
myIOParmBlk.ioPosMode = fsFromStart;
myIOParmBlk.ioPosOffset = 0L;
myIOParmBlk.ioBuffer = (Ptr)HeaderPtr;
myIOParmBlk.ioReqCount = nBytes;
theErr = PBRead(&myIOParmBlk, FALSE);
if (theErr != noErr ) {
if ( theErr == eofErr ) {
PstringCopy((char *)theMess1, "\pEnd of file reached Header");
errorAlert(theMess1, NIL);
return(FALSE);
}
else {
PstringCopy((char *)theMess1, "\pError reading Header");
NumToString(theErr, &theMess2);
errorAlert(theMess1, theMess2);
return(FALSE);
}
}
fileSize = Header.FileSize;
SampleRate = Header.SampRate;
if ( !SDnoResource )
return(TRUE);
/* now scan the file to ascertain ma/min samples */
sampBufsz = RecLength;
theIbuf = (int *)NewPtr(sizeof(int) * sampBufsz);
if ( (theErr = MemError()) != noErr ) {
PstringCopy((char *)theMess1, "\pcan't get enough memory for theIbuf");
errorAlert(theMess1, NIL);
return(FALSE);
}
MinSample = 0.0;
MaxSample = 0.0;
bytesLeft = fileSize;
nrec = 0;
myIOParmBlk.ioPosMode = fsAtMark;
myIOParmBlk.ioPosOffset = NIL;
while ( bytesLeft > 0L ) {
if ( bytesLeft > RecLength )
nBytes = RecLength;
else
nBytes = bytesLeft;
myIOParmBlk.ioBuffer = (Ptr)theIbuf;
myIOParmBlk.ioReqCount = nBytes;
theErr = PBRead(&myIOParmBlk, FALSE);
if (theErr != noErr ) {
if ( theErr == eofErr ) {
PstringCopy((char *)theMess1, "\pEnd of file");
errorAlert(theMess1, NIL);
return(FALSE);
}
}
nBytes = myIOParmBlk.ioActCount;
if ( nBytes != myIOParmBlk.ioReqCount ) {
PstringCopy((char *)theMess1, "\pRead less bytes than expected");
errorAlert(theMess1, NIL);
}
nSamps = nBytes / sizeof(int);
for ( i = 0, Iptr = theIbuf; i < nSamps; i++ ) {
x = (double)(*Iptr++);
if ( x < MinSample )
MinSample = x;
if ( x > MaxSample )
MaxSample = x;
}
nrec++;
bytesLeft -= nBytes;
}
DisposPtr((Ptr)theIbuf);
return(TRUE);
}
Boolean SD2Info()
{
register double x;
register int i;
long nBytes;
OSErr theErr;
long sampBufsz;
long bytesLeft;
long RecLength = 2048L;
long nSamps;
int *theIbuf, *Iptr;
myIOParmBlk.ioCompletion = NIL;
PBGetEOF(&myIOParmBlk, FALSE);
if ( (fileSize = (long)myIOParmBlk.ioMisc) <= 0 ) {
PstringCopy((char *)theMess1,"\pFile is empty!");
errorAlert(theMess1, NIL);
return(FALSE);
}
/* now scan the file to ascertain max/min samples */
sampBufsz = RecLength;
theIbuf = (int *)NewPtr(sizeof(int) * sampBufsz);
if ( (theErr = MemError()) != noErr ) {
PstringCopy((char *)theMess1, "\pcan't get enough memory for theIbuf");
errorAlert(theMess1, NIL);
return(FALSE);
}
MinSample = 0.0;
MaxSample = 0.0;
bytesLeft = fileSize;
nrec = 0;
myIOParmBlk.ioPosMode = fsAtMark;
myIOParmBlk.ioPosOffset = NIL;
while ( bytesLeft > 0L ) {
if ( bytesLeft > RecLength )
nBytes = RecLength;
else
nBytes = bytesLeft;
myIOParmBlk.ioBuffer = (Ptr)theIbuf;
myIOParmBlk.ioReqCount = nBytes;
theErr = PBRead(&myIOParmBlk, FALSE);
if (theErr != noErr ) {
if ( theErr == eofErr ) {
PstringCopy((char *)theMess1, "\pEnd of file");
errorAlert(theMess1, NIL);
return(FALSE);
}
}
nBytes = myIOParmBlk.ioActCount;
if ( nBytes != myIOParmBlk.ioReqCount ) {
PstringCopy((char *)theMess1, "\pRead less bytes than expected");
errorAlert(theMess1, NIL);
}
nSamps = nBytes / sizeof(int);
for ( i = 0, Iptr = theIbuf; i < nSamps; i++ ) {
x = (double)(*Iptr++);
if ( x < MinSample )
MinSample = x;
if ( x > MaxSample )
MaxSample = x;
}
nrec++;
bytesLeft -= nBytes;
}
DisposPtr((Ptr)theIbuf);
return(TRUE);
}
void CheckSystem()
{
theErr = SysEnvirons(1, &SysEnvData);
if (SysEnvData.hasFPU)
return;
PstringCopy((char *)theMess1,"\pThis version of SFInfo requires a floating point unit");
errorAlert(theMess1, NIL);
ExitToShell();
}
void GetMusic4C_Prefs()
{
int refNum;
StringPtr volName;
char buffer[2];
long count;
Str255 FileFormat;
int i;
/* "Music4C_Prefs" is kept in the System Folder */
SFDirectoryName[0] = 0;
theErr = FSOpen("\pMusic4C_Prefs", SysEnvData.sysVRefNum, &refNum);
if (theErr == noErr) {
count = 2L;
theErr = FSRead (refNum, &count, &buffer);
if ( theErr != noErr ) {
PstringCopy((char *)theMess1, "\pError reading Preferences file");
OSError(theMess1, NIL);
}
count = sizeof(FileFormat);
theErr = FSRead (refNum, &count, &FileFormat);
if ( theErr != noErr ) {
PstringCopy((char *)theMess1, "\pError reading Preferences file");
OSError(theMess1, NIL);
}
count = sizeof(SFDirectoryName);
theErr = FSRead (refNum, &count, &SFDirectoryName);
if ( theErr != noErr ) {
PstringCopy((char *)theMess1, "\pError reading Preferences file");
OSError(theMess1, NIL);
}
theErr = FSClose(refNum);
}
}